﻿using System;
using System.Globalization;
using System.IO;
using System.Threading;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using Ctef.Web.Controllers;
using Ctef.Web.Extensions;

namespace Ctef.Web
{
    // Note: For instructions on enabling IIS6 or IIS7 classic mode, 
    // visit http://go.microsoft.com/?LinkId=9394801

    public class MvcApplication : HttpApplication
    {
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
            routes.IgnoreRoute("blog/{*pathInfo}");
            routes.IgnoreRoute("forum/{*pathInfo}");
            routes.IgnoreRoute("robots.txt/{*pathInfo}");
            routes.IgnoreRoute("Account/{*pathInfo}");
            routes.IgnoreRoute("stats/{*pathInfo}");

            // Legacy support for link at https://ctef.donortools.com/my/funds/13252-1-1-Student-Sponsorship
            routes.MapRoute(
                null,
                "OurProjects_sponsorship.asp",
                new { controller = "Programs", action = "SponsorshipRedirect" }
                );

            // Legacy support for link at https://ctef.donortools.com/my/funds/13302-Yushu-Earthquake-Relief-Fund
            routes.MapRoute(
                null,
                "OurProjects_earthquake.asp",
                new { controller = "Programs", action = "EarthquakeRelief" }
                );

            routes.MapRoute(
                "Default",
                "{controller}/{action}/{id}",
                new { controller = "Home", action = "Index", id = "" }
              );

            ControllerBuilder.Current.SetControllerFactory(new DebugControllerFactory());
        }

        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();

            RegisterRoutes(RouteTable.Routes);

            var path = Path.Combine(Server.MapPath("~/"), @"App_Data\log.txt");
            using (var s = File.AppendText(path))
            {
                LogInfo(s, "Application started.");
            }
        }

        protected void Application_End()
        {
            var path = Path.Combine(Server.MapPath("~/"), @"App_Data\log.txt");
            using (var s = File.AppendText(path))
            {
                LogInfo(s, "Application ended.");
            }
        }

        protected void Application_Error(object sender, EventArgs e)
        {
            // Get the error details
            HttpException lastErrorWrapper = Server.GetLastError() as HttpException;

            Exception lastError = lastErrorWrapper;
            if (lastErrorWrapper.InnerException != null)
                lastError = lastErrorWrapper.InnerException;

            string lastErrorTypeName = lastError.GetType().ToString();
            string lastErrorMessage = lastError.Message;
            string lastErrorStackTrace = lastError.StackTrace;

            var path = Path.Combine(Server.MapPath("~/"), @"App_Data\log.txt");
            using (var s = File.AppendText(path))
            {
                LogInfo(s, "Application error.");
                s.WriteLine("Error type: {0} Error message: {0}", lastErrorTypeName, lastErrorMessage);
                s.WriteLine(lastErrorStackTrace);
            }
        }

        protected void Application_AcquireRequestState(object sender, EventArgs e)
        {
            if (HttpContext.Current.Session == null)
            {
                return;
            }

            var ci = (CultureInfo)Session["Culture"];
            if (ci == null)
            {
                var userLanguages = HttpContext.Current.Request.UserLanguages;
                var defaultLang = "en";

                if (!userLanguages.IsNullOrEmpty())
                {
                    defaultLang = userLanguages[0].Substring(0, 2);
                    if (defaultLang.Equals("zh", StringComparison.OrdinalIgnoreCase))
                    {
                        defaultLang = GetSpecificChineseCulture(userLanguages[0]);
                    }
                }

                ci = new CultureInfo(defaultLang);
                Session["Culture"] = ci;
            }

            Thread.CurrentThread.CurrentUICulture = ci;
            Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(ci.Name);
        }

        private static string GetSpecificChineseCulture(string lang)
        {
            switch (lang.ToLowerInvariant())
            {
                case "zh-hk":
                case "zh-tw":
                case "zh-mo":
                    return "zh-TW";

                default:
                    return "zh-CN";
            }
        }

        private static void LogInfo(StreamWriter s, string message = "")
        {
            s.WriteLine("{0}: {1}", DateTime.Now, message);
        }
    }

    public class DebugControllerFactory : DefaultControllerFactory
    {
        public override IController CreateController(RequestContext requestContext, string controllerName)
        {
            IController ctl = null;
            try
            {
                ctl = base.CreateController(requestContext, controllerName);
            }
            catch (Exception e)
            {
                if (requestContext != null && requestContext.HttpContext != null &&
                requestContext.HttpContext.Request != null && !string.IsNullOrEmpty(requestContext.HttpContext.Request.PhysicalApplicationPath))
                {
                    var path = Path.Combine(requestContext.HttpContext.Request.PhysicalApplicationPath, @"App_Data\log.txt");
                    using (var s = File.AppendText(path))
                    {
                        s.WriteLine("{0}: controllerName = {1}, url = {2}", DateTime.Now, controllerName, requestContext.HttpContext.Request.RawUrl);
                        s.WriteLine(e.ToString());
                        s.WriteLine(e.Message);
                        s.WriteLine(e.StackTrace);
                    }
                }
            }

            return ctl ?? new HomeController();
        }  
    }
}